Thermal Comfort • Microclimate

THI – Temperature Humidity Index

The Temperature Humidity Index (THI) is a thermal comfort indicator that combines air temperature and relative humidity to estimate heat stress on humans or animals. It is widely used in urban climate, biometeorology, and livestock studies.

1. Concept & Formula

The THI integrates air temperature (T) and relative humidity (RH) to describe how “hot it feels” rather than temperature alone. It is particularly useful for evaluating heat stress in cities, outdoor workers, and livestock.

Common THI Formula (°C version)

THI = T - (0.55 - 0.0055 × RH) × (T - 14.5)

Where:

  • T: air temperature in °C (e.g. 2 m air temperature)
  • RH: relative humidity in %
  • THI: dimensionless comfort index Higher = more heat stress

Typical Interpretation (example ranges)

THI Range Interpretation
< 20 Comfortable / no heat stress
20 – 23 Mild heat stress (warm but tolerable)
23 – 26 Moderate heat stress (uncomfortable, caution)
26 – 30 Severe heat stress (danger for sensitive groups)
> 30 Very severe / dangerous heat stress

Thresholds can vary slightly between studies, climates, and whether the focus is on humans or livestock. Always adapt ranges to your specific application.

2. Data & Practical Use

Data Sources in Google Earth Engine

  • ERA5-Land (ECMWF/ERA5_LAND/HOURLY)
    Hourly 2 m air temperature and dew point temperature at ~11 km resolution, suitable for large-scale THI mapping.
  • Meteorological stations / in-situ data
    Can be combined with satellite-based land cover or LST to analyse local patterns.

Good Practice

  • Use a period that matches your analysis (e.g. daily mean in heat wave days).
  • Mask out oceans if you focus on land / urban areas.
  • Compare THI with population or land use layers to identify vulnerable zones.

Typical Applications

  • Urban heat stress mapping and microclimate assessment
  • Outdoor workers’ thermal comfort analysis
  • Livestock heat stress monitoring in agricultural areas

3. Google Earth Engine Code – THI from ERA5-Land

Steps: open code.earthengine.google.com → New Script → paste the code → draw your AOI as geometry on the map → click Run. This example uses ERA5-Land hourly data to derive temperature (°C), relative humidity (%), and then THI.

// THI (Temperature Humidity Index) for any AOI using ERA5-Land
// -------------------------------------------------------------
// 1) Go to: https://code.earthengine.google.com
// 2) Click "New Script" and paste this code.
// 3) On the map: draw your AOI (Polygon/Rectangle).
//    It will appear as a variable named 'geometry' in the left panel.
// 4) Click "Run" to display THI.
// 5) Optionally export THI as GeoTIFF to Google Drive.

// -------------------------------------------------------
// 1. Define Area of Interest (AOI)
// -------------------------------------------------------
var roi = geometry;  // Make sure a 'geometry' object exists in the left panel

// Center the map on the AOI
Map.centerObject(roi, 7);

// -------------------------------------------------------
// 2. Define time period
// -------------------------------------------------------
var startDate = '2023-07-01';
var endDate   = '2023-07-31';   // e.g. one month of summer

// -------------------------------------------------------
// 3. Load ERA5-Land hourly data
//    Dataset: ECMWF/ERA5_LAND/HOURLY
//    Bands used: temperature_2m, dewpoint_temperature_2m
// -------------------------------------------------------
var era5 = ee.ImageCollection('ECMWF/ERA5_LAND/HOURLY')
  .filterDate(startDate, endDate)
  .filterBounds(roi)
  .select(['temperature_2m', 'dewpoint_temperature_2m'])
  .mean()   // average over the chosen period
  .clip(roi);

// Convert from Kelvin to Celsius
var tempC = era5.select('temperature_2m').subtract(273.15).rename('T_C');
var dewC  = era5.select('dewpoint_temperature_2m').subtract(273.15).rename('TD_C');

// -------------------------------------------------------
// 4. Compute Relative Humidity (%) from temperature & dew point
//    Using standard approximation:
//    RH = 100 * exp((17.625 * TD)/(243.04 + TD)) / exp((17.625 * T)/(243.04 + T))
// -------------------------------------------------------
var rh = ee.Image().expression(
  "100 * (exp((17.625 * TD)/(243.04 + TD)) / exp((17.625 * T)/(243.04 + T)))",
  {
    T:  tempC,
    TD: dewC
  }
).rename('RH');

// Clip RH to [0,100] for safety
rh = rh.max(0).min(100);

// -------------------------------------------------------
// 5. Compute THI (Celsius-based formulation)
//    THI = T - (0.55 - 0.0055 * RH) * (T - 14.5)
// -------------------------------------------------------
var thi = ee.Image().expression(
  "T - (0.55 - 0.0055 * RH) * (T - 14.5)",
  {
    T:  tempC,
    RH: rh
  }
).rename('THI');

// -------------------------------------------------------
// 6. Define visualisation parameters & display
// -------------------------------------------------------
var thiVis = {
  min: 15,
  max: 35,
  palette: [
    '#31316b', // cool
    '#3b82f6',
    '#22c55e',
    '#eab308',
    '#f97316',
    '#b91c1c'  // very hot / strong stress
  ]
};

Map.addLayer(thi, thiVis, 'THI (ERA5-Land)', true);

// Optionally show T and RH for context
Map.addLayer(tempC, {min: 15, max: 35, palette: ['#0ea5e9','#f97316','#b91c1c']}, 'Air Temperature (°C)', false);
Map.addLayer(rh,    {min: 20, max: 100, palette: ['#f9fafb','#38bdf8','#1d4ed8']}, 'Relative Humidity (%)', false);

// -------------------------------------------------------
// 7. Export THI as GeoTIFF to Google Drive (optional)
// -------------------------------------------------------
Export.image.toDrive({
  image: thi,
  description: 'THI_ERA5Land_Export',
  fileNamePrefix: 'THI_ERA5Land',
  region: roi,
  scale: 10000,           // ~10 km (ERA5-Land native ~11 km)
  crs: 'EPSG:4326',
  maxPixels: 1e13
});